package com.powroznik.tracker.client.android;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class TrackerService5 extends Service {
	public class TrackerService5Binder extends Binder {
		public TrackerService5 getService() {
			Log.d("TS5B", "getService");
			return TrackerService5.this;
		}
	}

	private DefaultHttpClient getDefaultHttpClient() {
		Log.d("TS5", "getDefaultHttpClient");
		DefaultHttpClient defaultHttpClient1 = new DefaultHttpClient();
		HttpParams httpParams = defaultHttpClient1.getParams();
		HttpConnectionParams.setConnectionTimeout(httpParams, 15 * 1000);
		HttpConnectionParams.setSoTimeout(httpParams, 15 * 1000);
		ClientConnectionManager clientConnectionManager = defaultHttpClient1
				.getConnectionManager();
		DefaultHttpClient defaultHttpClient2 = new DefaultHttpClient(
				new ThreadSafeClientConnManager(httpParams,
						clientConnectionManager.getSchemeRegistry()),
				httpParams);
		return defaultHttpClient2;
	}

	public DeviceConfiguration getDeviceConfiguration(String server,
			Device device) {
		try {
			Log.d("TS5", "getDeviceConfiguration");
			HttpPost httpPost = new HttpPost(
					"http://"
							+ server
							+ "/TrackerEngine/services/rest/deviceService/getDeviceConfiguration");
			httpPost.setHeader("Host", "www.powroznik.com");
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new BasicNameValuePair("device", ConversionUtils
					.writeDevice(device)));
			httpPost.setEntity(new UrlEncodedFormEntity(params));
			HttpResponse httpResponse = getDefaultHttpClient()
					.execute(httpPost);
			validateResponse(httpResponse);
			HttpEntity httpEntity = httpResponse.getEntity();
			InputStream inputStream = httpEntity.getContent();
			return ConversionUtils.readDeviceConfiguration(ConversionUtils
					.readString(inputStream));
		} catch (Throwable t) {
			Log.w("TS5", t);
			// throw new RuntimeException(t);
			return null;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.d("TS5", "onBind");
		return new TrackerService5Binder();
	}

	public String ping(String server, String message) {
		try {
			Log.d("TS5", "ping");
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new BasicNameValuePair("message", message));
			HttpGet httpGet = new HttpGet("http://" + server
					+ "/TrackerEngine/services/rest/deviceService/ping?"
					+ URLEncodedUtils.format(params, "UTF-8"));
			httpGet.setHeader("Host", "www.powroznik.com");
			HttpResponse httpResponse = getDefaultHttpClient().execute(httpGet);
			validateResponse(httpResponse);
			HttpEntity httpEntity = httpResponse.getEntity();
			InputStream inputStream = httpEntity.getContent();
			return ConversionUtils.readString(inputStream);
		} catch (Throwable t) {
			Log.w("TS5", t);
			// throw new RuntimeException(t);
			return null;
		}
	}

	public Device registerNewDevice(String server) {
		try {
			Log.d("TS5", "registerNewDevice");
			HttpGet httpGet = new HttpGet(
					"http://"
							+ server
							+ "/TrackerEngine/services/rest/deviceService/registerNewDevice");
			httpGet.setHeader("Host", "www.powroznik.com");
			HttpResponse httpResponse = getDefaultHttpClient().execute(httpGet);
			validateResponse(httpResponse);
			HttpEntity httpEntity = httpResponse.getEntity();
			InputStream inputStream = httpEntity.getContent();
			return ConversionUtils.readDevice(ConversionUtils
					.readString(inputStream));
		} catch (Throwable t) {
			Log.w("TS5", t);
			// throw new RuntimeException(t);
			return null;
		}
	}

	public boolean saveLocations(String server, Device device,
			List<Location> locations) {
		try {
			Log.d("TS5", "saveLocations");
			HttpPost httpPost = new HttpPost(
					"http://"
							+ server
							+ "/TrackerEngine/services/rest/deviceService/saveLocations");
			httpPost.setHeader("Host", "www.powroznik.com");
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new BasicNameValuePair("device", ConversionUtils
					.writeDevice(device)));
			for (Location location : locations) {
				params.add(new BasicNameValuePair("locations", ConversionUtils
						.writeLocation(location)));
			}
			httpPost.setEntity(new UrlEncodedFormEntity(params));
			HttpResponse httpResponse = getDefaultHttpClient()
					.execute(httpPost);
			validateResponse(httpResponse);
			return true;
		} catch (Throwable t) {
			Log.w("TS5", t);
			// throw new RuntimeException(t);
			return false;
		}
	}

	private void validateResponse(HttpResponse httpResponse) {
		Log.d("TS5", "validateResponse");
		StatusLine statusLine = httpResponse.getStatusLine();
		int statusCode = statusLine.getStatusCode();
		if (statusCode < 200 || statusCode > 299) {
			throw new RuntimeException(
					"statusCode < 200 || statusCode > 299 (statusLine = "
							+ statusLine + ")");
		}
	}
}
